package com.mrx.commons.gateway.handler;

import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @author Mr.X
 * @since 2024/6/2 上午9:33
 */
@Service
public class DispatcherHandlerChain implements HandlerChain {

    @Resource
    private List<DispatchHandler> handlers;

    private static final Map<String, Object> context = new ConcurrentHashMap<>();

    private static final AtomicInteger currentHandler = new AtomicInteger(0);

    public void dispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
        ContextHolder.REQUEST.putObject(request);
        ContextHolder.RESPONSE.putObject(response);
        currentHandler.set(0);
        doDispatch(request, response);
    }

    @Override
    public void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
        handlers.get(currentHandler.getAndIncrement()).dispatchRequest(request, response, this);
    }

    public DispatcherHandlerChain putObject(String key, Object value) {
        context.put(key, value);
        return this;
    }

    @SuppressWarnings("unchecked")
    public <T> T getObject(String key) {
        return (T) context.get(key);
    }

    public enum ContextHolder {
        REQUEST, RESPONSE,
        ;

        @SuppressWarnings("unchecked")
        public <T> T getObject() {
            return (T) context.get(name());
        }

        public void putObject(Object value) {
            context.put(name(), value);
        }
    }

}
